package pua.uniandes.recepcion;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bouncycastle.util.encoders.Base64;
import pua.uniandes.paqueteAuxiliar.MD5;

/**
 * Clase que representa recepción experimento
 * @author Juan David Velasquez jd.velasquez3209@uniandes.edu.co
 * @author Rafael Carrillo re.carrillo571@uniandes.edu.co
 * @author Julian Riveros jc.riveros@uniandes.edu.co
 */
public class RecepcionExp2 {

        /**
	 * Atributo que representa la conexion con el cohete a través de un socket UDP
	 */
	private DatagramSocket conexionCohete;
	
	/**
	 * Atributo que representa la conexión con el Centro de Monitoreo a través de un socket TCP
	 */
	private Socket conexionCentro;
	
	/**
	 * Atributo que escribe por el socket hacia el Centro de Monitoreo
	 */
	private PrintWriter pw;

	/**
	 * Método constructor de la clase principal Recepción
	 */
	public RecepcionExp2()
	{
		recibirConexiones();
	}

	/**
	 * Método encargado de recibir las conexiones y establecerlas con el socket UDP.
         */
	public void recibirConexiones()
	{
		try{
			conexionCohete=new DatagramSocket(5555,InetAddress.getLocalHost());
			conexionCentro=new Socket("127.0.0.1", 7854);
			DatagramPacket paquete=new DatagramPacket(new byte[2000], 2000);
			pw=new PrintWriter(conexionCentro.getOutputStream(),true);

			while(true)
			{
				conexionCohete.receive(paquete);
				System.out.println("TiempoInicial:"+System.currentTimeMillis());
                                System.out.println("ANTES DE COMPROBAR INTEGRIDAD");
                                byte[] recibido= comprobarIntegridad(paquete.getData());
                                System.out.println("DESPUES DE COMPROBAR INTEGRIDAD");
                                if(recibido!=null)
                                {
//                                  String conv = conversion(recibido, recibido.length);
                                    pw.println(new String(recibido));
                                }

                                

			}
		}
		catch(IOException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * Método que se encarga de la decodificación de base 64 y convertir el conjunto de bytes a String.
	 * @param Arreglo de bytes codificados en base 64
	 * @param Longitud de la cadena.
	 * @return La cadena en String ya decodificada.
	 */
	public String conversion(byte[] bytes, int num)
	{
		byte[] arreglo=new byte[num-2];
		for (int i=0;i<num-2;i++)
		{
			arreglo[i]=bytes[i+1];
		}
		byte[]arregloDeco= Base64.decode(arreglo);
		String result=new String(arregloDeco);

		return result;
	}

        private byte[] comprobarIntegridad(byte[] cadenaInicial){
        String s=new String(cadenaInicial);
            System.out.println("CADENA INICIAL:"+s);
        String cadenaCifrada=s.split("RAFAELC")[0];
            System.out.println("CadenaCifrada:"+cadenaCifrada);
        String integridad=s.split("RAFAELC")[1];
            
         try {
            MD5 ejemplo = new MD5();
            ejemplo.Update(cadenaCifrada, null);
            String has2 = ejemplo.asHex();
            if(integridad.contains(has2)){
                System.out.println("LALA:" + s );
                return cadenaCifrada.getBytes();
            }
            else return null;
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(RecepcionExp2.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

	/**
	 * Método MAIN
	 * @param args
	 */
	public static void main (String[] args)
	{
		new RecepcionExp2();
	}       
}